package com.md5;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

public class FlowController extends FilterInputStream{    

    public static void main(String[] args){ 
        try{ 
            byte[] buffer = new byte[1024];        
            long start = System.currentTimeMillis(); 
            FileInputStream in1 = new FileInputStream("D:/123/1.jpg");
            BufferedInputStream in = new BufferedInputStream(in1);
            BufferedOutputStream write = new BufferedOutputStream(new FileOutputStream(new File("D:/123/g1.txt")));
            //设定速率10000�?0000=10kbps 
            FlowController fin = new FlowController(in, 10000);        
           // fin.update(1000);          
            System.out.println("当前速率"+fin.check()/1000+"kbps"); 
            System.out.println("文件大小"+fin.available()/1024+"kb"); 
            int i=-1;
            while( (i=fin.read(buffer)) > 0){
            	  write.write(buffer,0,i);   //写入
  				//	    write.write(b);   //写入  错误
  					    write.flush();
            	  
            }
            
            fin.close();     
            long end = System.currentTimeMillis(); 
            System.out.println("读取文件耗时"+(end-start)/600+"秒"); 
        }catch(IOException e){ 
            e.printStackTrace(); 
        } 
    } 
  

	public FlowController(InputStream in) {
		super(in);
	}


	private long timestamp; 
    private int maxbps; 
    private int currentbps; 
    private int bytesread; 
    
    //---------------------------------------------------------- 
    //constructor 
    public FlowController(InputStream in, int maxbps){ 
        super(in); 
        this.maxbps = maxbps; 
        this.currentbps = 0;        
        this.bytesread = 0; 
        this.timestamp = System.currentTimeMillis(); 
    } 
  
    //---------------------------------------------------------- 
    //decorated methods 
    
    public int read() throws IOException{ 
        synchronized(in){ 
            int avaliable = check(); 
            if(avaliable == 0){ 
                waitForAvailable(); 
                avaliable = check(); 
            } 
            int value = in.read(); 
            update(1); 
            return value; 
        } 
    } 

    public int read(byte[] b) throws IOException{ 
        return read(b, 0, b.length); 
       
    } 

    public int read(byte[] b, int off, int len) throws IOException{ 
        synchronized(in){ 
            int avaliable = check(); 
            if(avaliable == 0){ 
                waitForAvailable();                        
                avaliable = check(); 
            }        
            int n = in.read(b, off, Math.min(len, avaliable)); 
            update(n); 
            return n;   
        } 
    } 

    public int check(){ 
        long now = System.currentTimeMillis(); 
        if(now - timestamp >= 1000){ 
            timestamp = now; 
            currentbps = bytesread; 
            bytesread = 0; 
            return maxbps; 
        }else{ 
            return maxbps - bytesread; 
        } 
    } 

    private void waitForAvailable(){ 
        long time = System.currentTimeMillis() - timestamp; 
        boolean isInterrupted = false; 
        while(time < 1000){ 
            try{ 
                Thread.sleep(1000 - time); 
            }catch(InterruptedException e){ 
                isInterrupted = true; 
            } 
            time = System.currentTimeMillis() - timestamp; 
        } 
        if(isInterrupted) 
            Thread.currentThread().interrupt(); 
        return; 
        
    } 

    private void update(int n){ 
        bytesread += n; 
    } 
    
    public int getCurrentbps(){ 
        return currentbps; 
    } 
} 

